######################################################################################################################
# Proximity detection                                                                                                #
#                                                                                                                    #
# A script designed to run on a router running DD-WRT to detect certain devices connected to the router.             #
# It runs at startup and runs continually, checking for a specific list of devices (phones/laptop, etc)              #
# that connect wirelessly to the router.  Once a device is connected, the status is updated on the ISY               #
# with either a 0=disconnected, or a 1=connected.  State variables are used on the ISY so that a change              #
# in status (0/1) can trigger a programe on the ISY.                                                                 #
#                                                                                                                    #
# The searching frequency can be adjusted to be slower/faster depending on your requirements. Searching too fast     #
# could burden your router.  Too slow might not update the status as necessary for the application.                  #
######################################################################################################################

# Make changes below
# This variable turns on or off notifications to the syslog for debugging.
# Set 'notifications' to '1' to enable logging, set it to '0' to turn them off.
notifications=1	# Logging is enable by default. Change this to turn it off.



# MAC address of each device to watch. Don't leave blank.
# For security purposes, if your router requires a password, even if someone could clone the MAC of your
# phone, they would still require the password of your network to link to your router.

if [ $notifications -eq 1 ]; then logger -t PX_DETECT "Setting MACs"; fi	#Debug output to the syslog.
macdevice1="XX:XX:XX:XX:XX:XX"    	#Put the MAC address of the wifi adapater of the first device here.
macdevice2="XX:XX:XX:XX:XX:XX"    	#Put the MAC address of the wifi adapater of the second device here.

if [ $notifications -eq 1 ]; then		#Debug output to the syslog.
logger -t PX_DETECT "Set MACs:"			#Debug output to the syslog.
logger -t PX_DETECT "macdevice1=" $macdevice1	#Debug output to the syslog.
logger -t PX_DETECT "macdevice2=" $macdevice2	#Debug output to the syslog.
fi						#Debug output to the syslog.


if [ $notifications -eq 1 ]; then logger -t PX_DETECT "Setting ISY username, password and local IP"; fi #Debug output to the syslog.
# ISY username, password, and IP Address
username="username"
password="password"
IPAddr="isy-ipaddr"
if [ $notifications -eq 1 ]; then logger -t PX_DETECT "Set ISY username, password and local IP"; fi #Debug output to the syslog.

# State variable numbers on the ISY corresponding to each MAC above
# isyvartot is the cummulative number of devices (of the 4 above) that are
# currently connected.
isyvar1=X1
isyvar2=X2
isyvartot=X3


# Occupied and unoccupied delay in seconds to check status
# Adjust for shorter/longer wait times.  For instance, when one device is already
# connected, you might want to check less frequently.  This could also delay the
# notification of a disconnect.
delay_occupied=4
delay_unoccupied=2

# initial testing loop count - uncomment the counter near the bottom of the script for testing only.
limit=1000000
if [ $notifications -eq 1 ]; then logger -t PX_DETECT "Testing loop limit: " $limit; fi	#Debug output to the syslog.

###############################################
# do not change below here
###############################################

# DO NOT CHANGE THE LINE BELOW. THE "XXXX" IS WHAT *SHOULD& BE THERE!!!
# This creates a variable use to store the output from a single arp command
# so it can be tested multiple times for the presence of any of your devices.
# It is used to lower the number of times the arp command is run to a single
# time per test cycle. It also store the output in RAM as opposed to using
# additional resources to write it out to disk/nvram.
arpout=XXXX

sleep
#initialize internal variables

if [ $notifications -eq 1 ]; then logger -t PX_DETECT "Setting connection status to initial state of -1"; fi #Debug output to the syslog.
# status of each MAC. 0=disconnected. 1=connected.  -1 initially forces isy update first loop
macconnected1=-1
macconnected2=-1
connected=-1
# total number of currently conencted devices.
currentconnected=0

# initializing the counter at 1
counter=1

# initializing the interval counter to be used to output less frequently
# to the syslog service during the loop.
intervalcounter=1

if [ $notifications -eq 1 ]; then logger -t PX_DETECT "All variables and controls are set, beginning script logic/testing loop"; fi	#Debug output to the syslog.

# Initial testing loop.  Will run continually after testing is complete
while [ $counter -lt $limit ]; do

#if the interval counter is 1 then make a log entry.

if [ $notifications -eq 1 ]; then
  if [ $intervalcounter -eq 1 ]; then
     logger -t PX_DETECT "Test loop " $counter " of " $limit "is running."
  fi
fi
# Reset current status. Two variables are used for each device.  The past known status and the current
# status.  Only a change is reported to the ISY.  Otherwise, it would constantly be updating the ISY with
# the current status creating unnecessary traffic for both the router and the ISY
maccurrent1=0;
maccurrent2=0;

# This section compares the list of MACs you entered above against the output of a
# single arp command listing the MACs associated with the wired bridge of your
# router. Interface "br0"

# This command runs arp once and saves it in the 'arpout' variable in memory
arpout=$(arp -i br0)

# The following runs 'grep' against the output form 'arp' in order to see if your
# first entered MAC address is present on the network.
maccurrent1=$(echo $arpout | grep -c $macdevice1)
if [ $maccurrent1 -gt 0 ]; then
   maccurrent1=1
fi

# The following section checks the second MAC identical to method discussed in the
# section directly above. To check additional MACs this section can be copied and
# the numbers following 'maccurrent' and 'macdevice' should in incremented.
maccurrent2=$(echo $arpout | grep -c $macdevice2)
if [ $maccurrent2 -gt 0 ]; then
   maccurrent2=1
fi

# Look for a change in status from the old known to the current status.
# If it changed, update the ISY. Otherwise it leaves it as is.

if [ $macconnected1 -ne $maccurrent1 ]; then
   if [ $notifications -eq 1 ]; then logger -t PX_DETECT "Updating ISY upon status change of Device1. It is now: " $maccurrent1; fi	#Debug output to the syslog.
   wget -q http://$username:$password@$IPAddr/rest/vars/set/2/$isyvar1/$maccurrent1
fi

if [ $macconnected2 -ne $maccurrent2 ]; then
   if [ $notifications -eq 1 ]; then logger -t PX_DETECT "Updating ISY upon status change of Device2. It is now: " $maccurrent2; fi #Debug output to the syslog.
   wget -q http://$username:$password@$IPAddr/rest/vars/set/2/$isyvar2/$maccurrent2
fi

# Update the known status from the current.  Ready for the next loop.
macconnected1=$maccurrent1;
macconnected2=$maccurrent2;

# Total up the number of devices connected.
let currentconnected=$macconnected1+$macconnected2 #remember to add new devices to add up here in the total.

# Look for a change, and update the ISY.
if [ $connected -ne $currentconnected ]; then
   if [ $notifications -eq 1 ]; then logger -t PX_DETECT "Updating ISY upon status change in the total number of devices. It is now: " $currentconnected; fi #Debug output to the syslog.
   wget -q http://$username:$password@$IPAddr/rest/vars/set/2/$isyvartot/$currentconnected
fi

connected=$currentconnected

# Delay (sleep) depending on the connection status.
# No devices connected could delay less.  Once a device is connected, it could delay longer.

if [ $connected -gt 0 ]; then
   sleep $delay_occupied
else
   sleep $delay_unoccupied
fi

# For testing only - uncomment to have the looping stop at X loops defined in variable:  limit.
let counter=$counter+1

# Increment the interval counter
let intervalcounter=$intervalcounter+1

# If the interval counter is greater than 10, reset it to 1. This done to output items to
# the syslog once every 10 runs of the loop. The '10' below can be changed to output more
# or less to the syslog as desired, or commented out entirely to stop the log output.
if [ $intervalcounter -gt 10 ]; then
   let intervalcounter=1
fi

#end of testing loop
done

if [ $notifications -eq 1 ]; then logger -t PX_DETECT "Testing loop limit of " $limit " reached. Testing stopping."; fi #Debug output to the syslog.
